﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using RestSharp;
using System.Text;

namespace tDonkeySite.Controllers
{
    public class SchedulerController : Controller
    {
        
        //TODO: share the dictionary between all the connections. I thinks the 
        //folowing decleration is not shared.
        Dictionary<string, int> days = new Dictionary<string, int>(){
            {"א",0},
            {"ב",1},
            {"ג",2},
            {"ד",3},
            {"ה",4},
            {"ו",5},
        };

        CoursesCache CCache;

        public ActionResult Index()
        {
            return View();
        }

        /* TODO: I think we need to create new class called: Schedule, it will contains the groups and some other
         * information
         */
        public ActionResult Scheduler(string rank = "0", string[] freeDays = null, int numberOfFreeDays = 0,
                                      string[] choosenGroups = null, int dontShowOverlappedSchedules = 0, 
                                      int goPrev = 0, int noRunning = 0, string[] courses = null)
        {
            var client = new RestClient("http://tdonekyapi.yudapps.com/");
            //var client = new RestClient("http://localhost:45312/");
            var request = new RestRequest("api/Scheduler/", Method.GET);
            request.RequestFormat = DataFormat.Json;
            //TODO: check if Values not null and count!=0
            if (courses == null)
            {
                try
                {
                    courses = this.ControllerContext.HttpContext.Request.Cookies["Courses"].Values.AllKeys;
                }
                catch
                {
                    return null;
                }
            }
            foreach (string c in courses)
            {
                request.AddParameter("courses", c);
            }
            if (rank == "0")
            {
                //check if there is a value for rank cookie:
                if (this.ControllerContext.HttpContext.Request.Cookies["rankNum"] != null &&
                    !String.IsNullOrEmpty(this.ControllerContext.HttpContext.Request.Cookies["rankNum"].Value))
                {
                    rank = this.ControllerContext.HttpContext.Request.Cookies["rankNum"].Value;
                }
                else
                {
                    rank = "1"; //we may get to here in the first time we visit the schedule page and there is no cookies.
                }
            }
            request.AddParameter("rank", rank);
            if (freeDays != null)
	        {
               foreach (string hourConstraint in freeDays)
    	       {
    	           request.AddParameter("freeDays", hourConstraint);
    	       }
            }
            request.AddParameter("numberOfFreeDays", numberOfFreeDays);
            if (choosenGroups != null)
            {
                foreach (string choosenGroup in choosenGroups)
                {
                    request.AddParameter("choosenGroups", choosenGroup);
                }
            }
            request.AddParameter("dontShowOverlappedSchedules", dontShowOverlappedSchedules);
            request.AddParameter("goPrev", goPrev);
            request.AddParameter("noRunning", noRunning);

            IRestResponse<List<eDonkeyClassLibrary.Group>> response = client.Execute<List<eDonkeyClassLibrary.Group>>(request);
            if (response == null || response.Data == null || response.Data.Count == 0)
            {
                var emptyObj = new object[1];
                return Json(new { emptyObj, count = 0, rank = 1, max = 0}, null, JsonRequestBehavior.AllowGet);
            }
            List<eDonkeyClassLibrary.Group> groups = response.Data;

            int ptCount = 0, i = 0;
            //TODO: Try to return the ptCount from the webservice, that will save time...
            foreach (eDonkeyClassLibrary.Group group in groups)
            {
                ptCount += group.PlaceTimes.Count;
            }
            var jsTable = new object[ptCount];
            foreach (eDonkeyClassLibrary.Group group in groups)
            {
                if (group.PlaceTimes.Count > 0)
                {
                    foreach (eDonkeyClassLibrary.PlaceTime pt in group.PlaceTimes)
                    {
                        jsTable[i] =
                                new
                                {
                                    day = days[pt.Day.Trim()].ToString(),
                                    start = pt.StartTime.Trim(),
                                    duration = pt.Duration.Trim(),
                                    groupNumber = group.Number.ToString(),
                                    courseName = group.Course.Name,
                                    courseNumber = group.Course.Number,
                                    room = pt.Place.ToString(),
                                    groupRole = group.Role.ToString(),
                                };
                        i++;
                    }
                }
            }
            int? currentRank = groups[groups.Count - 1].Number;
            int maxNumOfRanks = groups[groups.Count - 1].Id;
            return Json(new { jsTable, count = ptCount , rank = currentRank, max = maxNumOfRanks}, null, JsonRequestBehavior.AllowGet);
        }


        public ActionResult ScheduleViewer(string rank = "1", string[] freeDays = null, int numberOfFreeDays = 0
                                      , string[] choosenGroups = null, int dontShowOverlappedSchedules = 0, int goPrev = 0,
                                        int noRunning = 0, string[] c = null)
        {
            ActionResult schedule = Scheduler(rank, freeDays, numberOfFreeDays, choosenGroups, dontShowOverlappedSchedules, goPrev, noRunning, c);
            ViewBag.j = schedule;
            return View();
        }


        public ActionResult getCordinates(string name = "")
        {
            var client = new RestClient("http://tdonekyapi.yudapps.com/");
            //var client = new RestClient("http://localhost:45312/");
            var request = new RestRequest("api/Scheduler/getBuildingCordinates", Method.GET);
            request.RequestFormat = DataFormat.Json;
            request.AddParameter("name", name);
            IRestResponse<List<double>> response = client.Execute<List<double>>(request);
            List<double> cor = response.Data;
            if (cor.Count == 0)
            {
                return Json(new { x = 0, y = 0 }, null, JsonRequestBehavior.AllowGet);
            }

            return Json(new { x = cor[0], y = cor[1] }, null, JsonRequestBehavior.AllowGet);

        }
        public ActionResult Exams()
        {
            IRestResponse<List<eDonkeyClassLibrary.Course>> response = null;
            var client = new RestClient("http://tdonekyapi.yudapps.com/");
            //var client = new RestClient("http://localhost:45312/");
            var request = new RestRequest("api/Courses/GetCourses/", Method.GET);

            //find another way to initialize the CCache
            if (HttpContext.Cache["C"] == null)
            {
                HttpContext.Cache["C"] = new CoursesCache(300);
            }
            CCache = (CoursesCache)HttpContext.Cache["C"];

            request.RequestFormat = DataFormat.Json;
            List<eDonkeyClassLibrary.Course> courses = new List<eDonkeyClassLibrary.Course>();
            //TODO: check if Values is not null and if it is really exist!
            List<string> coursesNumbers = this.ControllerContext.HttpContext.Request.Cookies["Courses"].Values.AllKeys.ToList();
            foreach (string c in coursesNumbers)
            {
                eDonkeyClassLibrary.Course cachedCourse = CCache.Find(c);
                if (cachedCourse == null)
                {
                    request.AddParameter("coursesNumbers", c);
                }
                else
                {
                    courses.Add(cachedCourse);
                }
            }
            if (coursesNumbers.Count != courses.Count)
            {
                response = client.Execute<List<eDonkeyClassLibrary.Course>>(request);
                if (response == null || response.Data == null)
                {
                    //TODO: I am not sure if this is true, we must return null (or empty json)!
                    return View();
                }
                foreach (eDonkeyClassLibrary.Course c in response.Data)
                {
                    CCache.Add(c);
                }
                courses.AddRange(response.Data);
            }
            int length = courses.Count;
            Dictionary<DateTime?, int> examADates = new Dictionary<DateTime?, int>();
            Dictionary<DateTime?, int> examBDates = new Dictionary<DateTime?, int>();

            for (int i = 0; i < length; ++i)
            {
                if (examADates.ContainsKey(courses[i].TermA) == false)
                {
                    examADates.Add(courses[i].TermA, 0);
                }
                else
                {
                    examADates[courses[i].TermA] = 1;
                }

                if (examBDates.ContainsKey(courses[i].TermB) == false)
                {
                    examBDates.Add(courses[i].TermB, 0);
                }
                else
                {
                    examBDates[courses[i].TermB] = 1;
                }
            }
            var examsJsonList = new object[length];

            for (int i = 0; i < length; ++i)
            {
                examsJsonList[i] = new
                {
                    name = courses[i].Name.ToString(),
                    number = courses[i].Number,
                    examA = courses[i].TermA.Value.Year.ToString() + "/" + courses[i].TermA.Value.Month.ToString(),
                    examAExists = examADates[courses[i].TermA].ToString(),
                    examB = courses[i].TermB.Value.Year.ToString() + "/" + courses[i].TermB.Value.Month.ToString(),
                    examBExists = examBDates[courses[i].TermB].ToString() //why you convert it to string?
                };
            }
            return Json(new { examsJsonList, length }, null, JsonRequestBehavior.AllowGet);
        }
    }
}
